package com.shangxian.giveithome.service.impl;

import com.shangxian.giveithome.code.CommonCode;
import com.shangxian.giveithome.entity.PageableDetails;
import com.shangxian.giveithome.entity.UserDetails;
import com.shangxian.giveithome.entity.petCard.PetCard;
import com.shangxian.giveithome.entity.petCard.PetCardQrCode;
import com.shangxian.giveithome.entity.petCard.PetVaccinesRecord;
import com.shangxian.giveithome.entity.petCard.ScanRecord;
import com.shangxian.giveithome.entity.petCard.inputParam.*;
import com.shangxian.giveithome.entity.petCard.outputParam.*;
import com.shangxian.giveithome.exception.ExceptionUtils;
import com.shangxian.giveithome.mapper.*;
import com.shangxian.giveithome.service.PetCardService;
import com.shangxian.giveithome.utils.PageUtils;
import com.shangxian.giveithome.utils.RedisUtils;
import com.shangxian.giveithome.utils.TimeDealUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @author coderFu
 * @create 2021/5/2
 */
@Service
public class PetCardServiceImpl implements PetCardService {

    @Resource
    private PetCardMapper petCardMapper;

    @Autowired
    private RedisUtils redisUtils;

    @Resource
    private PetCardQrCodeMapper petCardQrCodeMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private ScanRecordMapper scanRecordMapper;

    @Resource
    private PetVaccinesRecordMapper petVaccinesRecordMapper;



    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object findPetMessage(Long id, HttpServletRequest request, Address address) {
        PetCardDetails petCardDetails = new PetCardDetails();
       Object state =  petCardMapper.checkIsBindingPet(id);
       if (state == null){
           ExceptionUtils.error(CommonCode.DATA_ERROR);
       }
       Integer status  = (Integer)state;
        //检查该二维码是否已经绑定宠物
       if (status  == 0){
           petCardDetails.setState(0L);
           return petCardDetails;
       }

       if (status  ==1){
           //检查扫描者是否为医生
           UserDetails userDetails = redisUtils.getHeader(request);
           int count = userMapper.IsDoctor(userDetails.getId());
           if (count>0){
               //医生的状态为3
               petCardDetails.setState(3L);
               return petCardDetails;
           }
           //保存扫描记录
           TimeParam timeParam = TimeDealUtils.get();
           ScanRecord scanRecord = new ScanRecord();
           scanRecord.setScanYear(timeParam.getScanYear());
           scanRecord.setScanMonth(timeParam.getScanMonth());
           scanRecord.setScanHour(timeParam.getScanHour());
           scanRecord.setScanTime(timeParam.getScanTime());
           scanRecord.setScanProvince(address.getProvince());
           scanRecord.setScanCity(address.getCity());
           scanRecord.setScanCounty(address.getCounty());
           scanRecord.setScanUser(userDetails.getId());
           scanRecord.setPetCardCodeId(id);
           scanRecord.setScanAddress(address.getAddress());
           scanRecord.setLongitude(address.getLongitude());
           scanRecord.setLatitude(address.getLatitude());
           int count2 = scanRecordMapper.saveScanRecord(scanRecord);
           if (count2<0){
               ExceptionUtils.error(CommonCode.PARAMETER_ERROR);
           }
           //查询宠物详情信息
           Long petCardId = petCardMapper.findPetCardIdByQrCodeId(id);
           petCardDetails = petCardMapper.findPetCardDetails(petCardId);
           petCardDetails.setState(1L);
           return petCardDetails;
       }
       //二维码信息不可见
       petCardDetails.setState(2L);
       return petCardDetails;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void bandingPetMessage(BandingPetMessage bandingPetMessage, HttpServletRequest request) {
        if (bandingPetMessage == null){
            ExceptionUtils.error(CommonCode.DATA_ERRORS);
        }
        Object state = petCardMapper.checkIsBindingPet(bandingPetMessage.getId());
        Integer status  = (Integer)state;
        if (status ==1){
            ExceptionUtils.error(CommonCode.PET_CARD_IS_BANDING);
        }

        UserDetails userDetails = redisUtils.getHeader(request);
        PetCard petCard = new PetCard();
        petCard.setPetName(bandingPetMessage.getPetName());
        petCard.setPetVariety(bandingPetMessage.getPetVariety());
        petCard.setPetType(bandingPetMessage.getPetType());
        petCard.setPetSex(bandingPetMessage.getPetSex());
        petCard.setPetBirthday(bandingPetMessage.getPetBirthday());
        petCard.setKeyId(bandingPetMessage.getKeyId());
        petCard.setUserName(bandingPetMessage.getUserName());
        petCard.setPhone(bandingPetMessage.getPhone());
        petCard.setProvince(bandingPetMessage.getProvince());
        petCard.setCity(bandingPetMessage.getCity());
        petCard.setCounty(bandingPetMessage.getCounty());
        petCard.setAddress(bandingPetMessage.getAddress());
        petCard.setLoseMessage(bandingPetMessage.getLoseMessage());
        petCard.setUserId(userDetails.getId());
        petCard.setCreateTime(new Date());
        petCard.setWechat(bandingPetMessage.getWechat());
        petCard.setState(0);
        petCard.setPetColor(bandingPetMessage.getPetColor());
        int count = petCardMapper.bandingPetMessage(petCard);
        if (count<=0){
            ExceptionUtils.error(CommonCode.PARAMETER_ERROR);
        }


        PetCardQrCode petCardQrCode = new PetCardQrCode();
        petCardQrCode.setId(bandingPetMessage.getId());
        petCardQrCode.setPetCardId(petCard.getId());
        petCardQrCode.setUpdateTime(new Date());
        petCardQrCode.setState(1);
        System.out.println(petCardQrCode);
        petCardQrCodeMapper.bandingPetMessage(petCardQrCode);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void recordInoculationMessage(VaccinesMessageParam vaccinesMessageParam, HttpServletRequest request) {
        TimeParam timeParam = TimeDealUtils.get();
        PetVaccinesRecord petVaccinesRecord = new PetVaccinesRecord();
        petVaccinesRecord.setInoculationYear(timeParam.getScanYear());
        petVaccinesRecord.setInoculationMonth(timeParam.getScanMonth());
        petVaccinesRecord.setVaccinesVariety(vaccinesMessageParam.getVaccinesVariety());
        petVaccinesRecord.setInoculationTime(vaccinesMessageParam.getInoculationTime());
        petVaccinesRecord.setPetCardCodeId(vaccinesMessageParam.getPetCardCodeId());
        UserDetails userDetails = redisUtils.getHeader(request);
        petVaccinesRecord.setDoctorId(userDetails.getId());
        int count = petVaccinesRecordMapper.recordInoculationMessage(petVaccinesRecord);
        if (count<1){
            ExceptionUtils.error(CommonCode.PARAMETER_ERROR);
        }
    }

    @Override
    public PageableDetails findActionRecord(Long id, Pageable pageable) {
        int pageSize = pageable.getPageSize();
        int pageNumber = pageable.getPageNumber();
        int total = scanRecordMapper.findAllScanRecordCount();
        List<ScanRecordDetails> scanRecordDetails = scanRecordMapper.findScanRecordByPetCardCodeId(id,pageNumber*pageSize,pageSize);
            ArrayList<String> years = new ArrayList<>();
            ArrayList<String> monthAndDays = new ArrayList<>();
            //找出所有年份，每个年份都有一个Map
            for (ScanRecordDetails s : scanRecordDetails) {
                if (!years.contains(s.getScanYear()+"")){
                    years.add(s.getScanYear()+"");
                }
                if (!monthAndDays.contains(s.getScanMonth())){
                    monthAndDays.add(s.getScanMonth());
                }
            }
            //HashMap<String,map<String,List<E>>>
            LinkedHashMap<String, Map<String, List<ScanRecordDetails>>> result = new LinkedHashMap<>();
            for(String year:years){
                result.put(year,new LinkedHashMap<String, List<ScanRecordDetails>>());
            }
            //把所有月份都添加到对应的年里
            result.forEach((a,b)->{
                for(String monthAndDay:monthAndDays){
                    b.put(monthAndDay,new LinkedList<>());
                }
            });
            scanRecordDetails.forEach(a->{
                String detailYear = a.getScanYear()+"";
                Map<String, List<ScanRecordDetails>> stringListMap = result.get(detailYear);
                String dayOfDetail = a.getScanMonth();
                List<ScanRecordDetails> scanRecordDetailsA = stringListMap.get(dayOfDetail);
                scanRecordDetailsA.add(a);
            });
            return new PageableDetails<>(pageNumber,pageSize,total,returnPages(total,pageSize),result);
    }

//    @Override
//    public PageableDetails findActionRecord(Long id, Pageable pageable) {
//        int pageSize = pageable.getPageSize();
//        int pageNumber = pageable.getPageNumber();
//        int total = scanRecordMapper.findAllScanRecordCount();
//        List<ScanRecordDetails> scanRecordDetails = scanRecordMapper.findScanRecordByPetCardCodeId(id,pageNumber*pageSize,pageSize);
//        List<String> scanMonths = scanRecordDetails.stream().map(ScanRecordDetails::getScanMonth).collect(Collectors.toList());
//        LinkedHashMap<String, List<ScanRecordDetails>> hashMap = new LinkedHashMap<>();
//        scanMonths.forEach(s -> {
//            hashMap.put(s,new ArrayList<ScanRecordDetails>());
//        });
//        scanRecordDetails.forEach(scanRecordDetails2 -> {
//            hashMap.forEach((a,b)->{
//                if (scanRecordDetails2.getScanMonth().equals(a)){
//                    b.add(scanRecordDetails2);
//                }
//            });
//        });
//        return new PageableDetails<>(pageNumber,pageSize,total,returnPages(total,pageSize),hashMap);
//    }

    //优化版本
    @Override
    public List<InoculationRecordDetails> findInoculationRecord(Long id) {
        List<InoculationRecordDetails> inoculationRecordDetails = petVaccinesRecordMapper.findInoculationRecord(id);
        return inoculationRecordDetails;
    }

    //先前版本
    //@Override
//    public LinkedHashMap<String, LinkedHashSet<LinkedHashMap<String,LinkedHashSet<InoculationRecordDetails>>>> findInoculationRecord(Long id ) {
//        List<InoculationRecordDetails> inoculationRecordDetails = petVaccinesRecordMapper.findInoculationRecord(id);
//        List<String> inoculationYears = inoculationRecordDetails.stream().map(InoculationRecordDetails::getInoculationYear).collect(Collectors.toList());
//        List<String> inoculationMonths = inoculationRecordDetails.stream().map(InoculationRecordDetails::getInoculationMonth).collect(Collectors.toList());
//        LinkedHashMap<String, LinkedHashSet<LinkedHashMap<String,LinkedHashSet<InoculationRecordDetails>>>> hashMapT = new LinkedHashMap<>();
//        inoculationYears.forEach(s->{
//            hashMapT.put(s,new LinkedHashSet<LinkedHashMap<String,LinkedHashSet<InoculationRecordDetails>>>());
//        });
//        LinkedHashMap<String,LinkedHashSet<InoculationRecordDetails>> hashMap = new LinkedHashMap<>();
//        inoculationMonths.forEach(s->{
//            hashMap.put(s,new LinkedHashSet<InoculationRecordDetails>());
//        });
//        System.out.println(hashMapT);
//
//        System.out.println("-----------");
//        System.out.println(inoculationRecordDetails);
//        System.out.println("-----------");
//        inoculationRecordDetails.forEach(InoculationRecordDetails->{
//            hashMapT.forEach((a,b)->{
//                System.out.println(a);
//                if (InoculationRecordDetails.getInoculationYear().equals(a)){
//                    hashMap.forEach((c,d)->{
//                        System.out.println(c);
//                        if (InoculationRecordDetails.getInoculationMonth().equals(c) && InoculationRecordDetails.getInoculationYear().equals(a)){
//                            d.add(InoculationRecordDetails);
//                        }
//                    });
//                }
//                b.add(hashMap);
//            });
//
//        });
//
//        return hashMapT;
//    }

    @Override
    public List<PetCardDetails> findMyPetCardMessages(HttpServletRequest request) {
        UserDetails userDetails = redisUtils.getHeader(request);
        return petCardMapper.findMyPetCardMessages(userDetails.getId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePetCardMessage(BandingPetMessage bandingPetMessage) {
        Long petCardId = petCardMapper.findPetCardIdByQrCodeId(bandingPetMessage.getId());
        bandingPetMessage.setId(petCardId);
        int count = petCardMapper.updatePetCardMessage(bandingPetMessage);
        if (count<1){
            ExceptionUtils.error(CommonCode.DATA_ERRORS);
        }
    }

    @Override
    public BandingPetMessage findPetMessageById(Long id) {
        BandingPetMessage petMessage = petCardMapper.findPetMessageById(id);
        if (petMessage == null){
            ExceptionUtils.error(CommonCode.DATA_ERROR);
        }
        return petMessage;
    }

    @Override
    public String findPetQrCodePathById(Long id) {
        String path = petCardQrCodeMapper.findPetQrCodePathById(id);
        if (path == null){
            ExceptionUtils.error(CommonCode.DATA_ERROR);
        }
        return path;
    }

    @Override
    public PetCardDetails findPetCardDetailsByQrId(Long id) {
        PetCardDetails petCardDetails = null;
        Long petCardId = petCardMapper.findPetCardIdByQrCodeId(id);
        if (petCardId !=null){
             petCardDetails = petCardMapper.findPetCardDetails(petCardId);
        }
        return petCardDetails ;
    }

    @Override
    public PageableDetails backFindPetCardList(Pageable pageable,BackSearchParam backSearchParam) {
        int pageNumber = pageable.getPageNumber();
        int pageSize = pageable.getPageSize();
        int total = petCardMapper.findAllPetCardCount(backSearchParam);
        if (total == 0){
            return new PageableDetails<>(pageNumber,pageSize,total,returnPages(total,pageSize),new ArrayList<>());
        }
        List<BackPetCardList> backPetCardLists = petCardMapper.findPetCardList(pageNumber*pageSize,pageSize,backSearchParam);
        return new  PageableDetails<>(pageNumber,pageSize,total,returnPages(total,pageSize),backPetCardLists) ;
    }

    @Override
    public BackPetCardDetails backFindPetCardDetailsById(Long id) {
        if (id == null){
            ExceptionUtils.error(CommonCode.PARAMETER_ERROR);
        }
        return petCardMapper.findPetCardDetailsById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void backUpdatePetCardMessage(BackUpdatePetCardParam backUpdatePetCardParam) {
        int count = petCardMapper.backUpdatePetCardMessage(backUpdatePetCardParam);
        if (count<1){
            ExceptionUtils.error(CommonCode.PARAMETER_ERROR);
        }
    }

    @Override
    public void backMakePetCert(Long id, String identityId) {
        int count = petCardMapper.backMakePetCert(id,identityId);
        if (count<1){
            ExceptionUtils.error(CommonCode.DATA_ERROR);
        }
    }

    @Override
    public List<BackVaccinesRecordList> backFindVaccinesRecordByPetCardCodeId(Long petCardCodeId) {
        return petVaccinesRecordMapper.backFindVaccinesRecordByPetCardCodeId(petCardCodeId);
    }

    @Override
    public void backAddVaccines(BackAddVaccinesParam backAddVaccinesParam) {
        Long petCardCodeId = Long.parseLong(backAddVaccinesParam.getPetCardNo());
        PetVaccinesRecord petVaccinesRecord = new PetVaccinesRecord();
        petVaccinesRecord.setDoctorId(1L);
        petVaccinesRecord.setPetCardCodeId(petCardCodeId);
        petVaccinesRecord.setVaccinesVariety(backAddVaccinesParam.getVaccinesVariety());
        petVaccinesRecord.setInoculationTime(backAddVaccinesParam.getInoculationTime());
        petVaccinesRecord.setInoculationMonth(TimeDealUtils.get().getScanMonth());
        petVaccinesRecord.setInoculationYear(TimeDealUtils.get().getScanYear());
        int count =  petVaccinesRecordMapper.backAddVaccines(petVaccinesRecord);
        if (count<1){
            ExceptionUtils.error(CommonCode.PARAMETER_ERROR);
        }
    }

    /**
     * 返回
     *
     * @param pageNumber 当前页
     * @param pageSize   每页条数
     * @param count      总条数
     * @param list       返回数据
     * @param <T>        泛型
     * @return
     */
    public <T> PageableDetails returnPageable(int pageNumber, Integer pageSize, Integer count, Map list) {
        return new PageableDetails<>(pageNumber, pageSize, count, list);
    }


    /**
     * 返回总页数
     *
     * @param total
     * @param pageSize
     * @return
     */
    public int returnPages(int total, int pageSize) {
        return PageUtils.returnPages(total, pageSize);
    }
}


